package net.labdemo.common.util;

import java.util.HashMap;
import java.util.Map;
/**
 * 构造分页页码结构
 * @author xiaofanku
 * 20160128
 */
public class IqidoPage {
	/**
	 * 用于计算结构需要的信息
	 */
	private PageHelper helper;
	/**
	 * 页码值显示的范围
	 */
	private final int pageNumberRange;
	/**
	 * 不含分页参数的连接地址
	 */
	private final String link;
	/**
	 * 分页查询参数
	 */
	private String pageSymbol="p";
	/**
	 * 查询参数分隔符
	 */
	private final char limit;
	
	/**
	 * 当连接不存在时的占位符
	 */
	public final static String flag="#";
	/**
	 * 初始化:需要显示页码数值
	 * 例如:prev|1,2,3|Next
	 * @param link 不包含分页查询参数的连接地址
	 * @param page 当前页
	 * @param pageSize 一页显示的记录数
	 * @param total 总记录数
	 * @param numberRange 页码值的范围
	 */
	public IqidoPage(
			String link,
			int page,
			int pageSize,
			int total,
			int numberRange
			) {
		// TODO Auto-generated constructor stub
		this.helper=new PageHelper(page,pageSize,total);
		
		this.link=link;
		this.limit=link.indexOf("?") != -1?'&':'?';
		this.pageNumberRange=numberRange;
	}
	/**
	 * 初始化:需要显示页码数值
	 * 例如:prev|Next
	 * @param link 不包含分页查询参数的连接地址
	 * @param page 当前页
	 * @param pageSize 一页显示的记录数
	 * @param total 条件的实体,无附加条件创建一个空实例即可
	 */
	public IqidoPage(
			String link,
			int page,
			int pageSize,
			int total
			){
		this.helper=new PageHelper(page,pageSize,total);
		
		this.link=link;
		this.limit=link.indexOf("?") != -1?'&':'?';
		this.pageNumberRange=1;
	}
	/**
	 * 设置显示分页的上限
	 * 默认为计算的上限
	 * @param showMaxPage
	 */
	public void setMaxPage(int showMaxPage){
		//计算的上限
		int maxPage=helper.getTotalPage();
		//设置了上限 && 计算的总页数大于上限
		if(showMaxPage>0 && maxPage>showMaxPage){
			helper.setTotalPage(showMaxPage);
		}
	}
	/**
	 * 设置分页查询参数
	 * @param symbol
	 */
	public void setPageSymbol(String symbol){
		this.pageSymbol=symbol;
	}
	/**
	 * 返回当前页码
	 * @return
	 */
	public int getCurrentPage(){
		return helper.getPage();
	}
	/**
	 * 是否存在下一页
	 * @return
	 */
	public boolean hasNext(){
		return helper.hasNext();
	}
	/**
	 * 是否存在上一页
	 * @return
	 */
	public boolean hasPrev(){
		return helper.hasPrev();
	}
	/**
	 * 计算上一页的页值
	 * @return  不存在上一页返回-1
	 */
	public int getPrevPager(){
		final int page=helper.getPage();
		if((page - 1) > 0){
			return page -1;
		}
		return -1;
	}
	/**
	 * 计算下一页的页值
	 * @return
	 */
	public int getNextPager(){
		final int totalPage=helper.getTotalPage();
		final int page=helper.getPage();
		if((page + 1) < totalPage){
			return page +1;
		}
		return totalPage;
	}
	/**
	 * 返回首页地址
	 * @return
	 */
	public String getHomeLink(){
		//link+?+p+"=1"
		if(helper.getTotalPage()>=1){
			return link+limit+pageSymbol+"=1";
		}
		return link+flag;
	}
	/**
	 * 返回尾页地址
	 * @return
	 */
	public String getTailLink(){
		if(helper.getTotalPage()>=1){
			return link+limit+pageSymbol+"="+helper.getTotalPage();
		}
		return link+flag;
	}
	/**
	 * 返回上一页地址
	 * @return
	 */
	public String getPrevLink(){
		String prevLink=link+limit+pageSymbol+"=";
		if(hasPrev()){
			return prevLink+(helper.getPage() - 1);
		}else{
			return prevLink+helper.getPage()+flag;
		}
	}
	/**
	 * 测试参数地址是否包含空白标识
	 * @param link
	 * @return 存在返回true,反之返回false
	 */
	private boolean isEmptyLink(final String link){
		return link.endsWith(flag)?true:false;
	}
	/**
	 * 返回下一页地址
	 * @return
	 */
	public String getNextLink(){
		String nextLink=link+limit+pageSymbol+"=";
		if(hasNext()){
			return nextLink+(helper.getPage() + 1);
		}else{
			return nextLink+helper.getPage()+flag;
		}
	}
	/**
	 * 显示:首页(home)|上一页(prev)|下一页(next)|尾页(end)总页数(size)
	 * @param isShowEmptyLink 当上一页和下一页不存在时是否显示,
	 *                                              false不显示无效的连接,true显示
	 * @return
	 */
	public Map<String,String> draw(final boolean isShowEmptyLink){
		Map<String,String> struct=new HashMap<>();
		final int pageCount=helper.getTotalPage();
		//防止无数据时显示1
		if(pageCount<1){
			return struct;
		}
		struct.put("home",getHomeLink());
		final String prevLink=getPrevLink();
		final String nextLink=getNextLink();
		//显示所有
		if(isShowEmptyLink){
			struct.put("prev", prevLink);
			struct.put("next", nextLink);
		//不显示不存在的连接
		}else{
			//如果不存在的:null
			//如果存在:显示
			struct.put("prev", isEmptyLink(prevLink)?null:prevLink);
			struct.put("next", isEmptyLink(nextLink)?null:nextLink);
		}
		struct.put("end",getTailLink());
		struct.put("size", pageCount+"");
		return struct;
	}
	
	public Map<Integer,String> drawPagination(){
		final int pageCount=helper.getTotalPage();
		final Map<Integer,String> pagination=new HashMap<Integer,String>();
		//防止无数据时显示1
		if(pageCount <1){
			return pagination;
		}
		
		final int currentPage=helper.getPage();
		final String procssurl=link+limit+pageSymbol+"=";
		//存在下一页
		if(getNextPager() != currentPage){
			int[] d=pagepanel(currentPage, pageCount);	
			for (int i=d[0]; i <= d[1]; i++) {
				pagination.put(Integer.valueOf(i),procssurl+i);
			}
		}else{
			for(int i=1;i<=pageCount;i++){
				pagination.put(Integer.valueOf(i),procssurl+i);
			}
		}
		return pagination;
	}
	/**
	 * drawPagePanel方法的助手方法.私有
	 * 返回一个关联数组.key说明:
	 *                              max:可视页码的上限数字
	 *                              low:可视页码的下限数字
	 *@param page 当前页
	 *@param pageCount 总页数
	 */
	private int[] pagepanel(int page,int pageCount){
		int[] data={0,0};
		//有至少一页
		//不够一段 或者刚好一段
		if(pageCount>=1 && pageCount<=pageNumberRange){
			data[0]=1;
			data[1]=pageCount;
		}
		//多于一段
		if(pageCount>pageNumberRange){
			//计算段数
			int howRang=pageCount / pageNumberRange;
			if(pageCount % pageNumberRange>0){
				howRang+=1;
			}
			int viewRangMax=0;
			for(int i=1;i<=howRang;i++){
				//计算当前段位的上限
				viewRangMax=i*pageNumberRange;
				if(page<=viewRangMax){
					break;
				}
			}
			data[0]=viewRangMax - pageNumberRange + 1;
			data[1]=viewRangMax;
		}
		return data;
	}
}
